package types
import (
"bytes"
"fmt"
"net"
"github.com/jcmturner/gofork/encoding/asn1"
"github.com/jcmturner/gokrb5/v8/iana/addrtype"
)
type HostAddresses []HostAddress
type HostAddress struct {
AddrType int32 `asn1:"explicit,tag:0"`
Address []byte `asn1:"explicit,tag:1"`
}
func GetHostAddress (s string ) (HostAddress , error ) {
var h HostAddress
cAddr , _ , err := net .SplitHostPort (s )
if err != nil {
return h , fmt .Errorf ("invalid format of client address: %v" , err )
}
ip := net .ParseIP (cAddr )
var ht int32
if ip .To4 () != nil {
ht = addrtype .IPv4
ip = ip .To4 ()
} else if ip .To16 () != nil {
ht = addrtype .IPv6
ip = ip .To16 ()
} else {
return h , fmt .Errorf ("could not determine client's address types: %v" , err )
}
h = HostAddress {
AddrType : ht ,
Address : ip ,
}
return h , nil
}
func (h *HostAddress ) GetAddress () (string , error ) {
var b []byte
_ , err := asn1 .Unmarshal (h .Address , &b )
return string (b ), err
}
func LocalHostAddresses () (ha HostAddresses , err error ) {
ifs , err := net .Interfaces ()
if err != nil {
return
}
for _ , iface := range ifs {
if iface .Flags &net .FlagLoopback != 0 || iface .Flags &net .FlagUp == 0 {
continue
}
addrs , err := iface .Addrs ()
if err != nil {
continue
}
for _ , addr := range addrs {
var ip net .IP
switch v := addr .(type ) {
case *net .IPNet :
ip = v .IP
case *net .IPAddr :
ip = v .IP
}
var a HostAddress
if ip .To16 () == nil {
continue
}
if ip .To4 () != nil {
a .AddrType = addrtype .IPv4
a .Address = ip .To4 ()
} else {
a .AddrType = addrtype .IPv6
a .Address = ip .To16 ()
}
ha = append (ha , a )
}
}
return ha , nil
}
func HostAddressesFromNetIPs (ips []net .IP ) (ha HostAddresses ) {
for _ , ip := range ips {
ha = append (ha , HostAddressFromNetIP (ip ))
}
return ha
}
func HostAddressFromNetIP (ip net .IP ) HostAddress {
if ip .To4 () != nil {
return HostAddress {
AddrType : addrtype .IPv4 ,
Address : ip .To4 (),
}
}
return HostAddress {
AddrType : addrtype .IPv6 ,
Address : ip .To16 (),
}
}
func HostAddressesEqual (h , a []HostAddress ) bool {
if len (h ) != len (a ) {
return false
}
for _ , e := range a {
var found bool
for _ , i := range h {
if e .Equal (i ) {
found = true
break
}
}
if !found {
return false
}
}
return true
}
func HostAddressesContains (h []HostAddress , a HostAddress ) bool {
for _ , e := range h {
if e .Equal (a ) {
return true
}
}
return false
}
func (h *HostAddress ) Equal (a HostAddress ) bool {
if h .AddrType != a .AddrType {
return false
}
return bytes .Equal (h .Address , a .Address )
}
func (h *HostAddresses ) Contains (a HostAddress ) bool {
for _ , e := range *h {
if e .Equal (a ) {
return true
}
}
return false
}
func (h *HostAddresses ) Equal (a []HostAddress ) bool {
if len (*h ) != len (a ) {
return false
}
for _ , e := range a {
if !h .Contains (e ) {
return false
}
}
return true
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .